package com.jackiechan.day16;

/**
 * 单例模式
 * 饿汉式:
 * 懒汉式: 按需加载,线程不安全必须加锁,写法复杂,面试爱考
 */
public class DesignPattern {
    public static void main(String[] args) {
        LanHanSingleton lanhan = LanHanSingleton.Born();
        LanHanSingleton lanhan1 = LanHanSingleton.Born();
        System.out.println(lanhan == lanhan1);
        System.out.println(lanhan1.i);
        lanhan.i++;
        System.out.println(lanhan1.i);
    }
}

// 饿汉式
class EHanSingleton {
    int i = 0;

    // 私有化构造方法,外界不能通过new创建对象
    private EHanSingleton() {
    }

    // 在内部创建一个对象, 给外界提供
    // 静态方法Born()只能调用静态资源
    static private EHanSingleton ehan = new EHanSingleton();

    // 给外界提供公共的方法, 返回ms
    // 外界无法创建对象,不能通过对象访问Born()方法,只能通过类名访问
    static public EHanSingleton Born() {
        return ehan;
    }

    public void play() {
        System.out.println(this.toString() + " play");
    }

}

// 懒汉式 -- 按需加载, 线程安全
// 多线程一定会有线程安全隐患, 可能有的线程拿到的是null
// 一定要加锁
class LanHanSingleton {
    int i = 0;

    private LanHanSingleton() {
    }

    static private LanHanSingleton lanhan;
    // 共享资源 lanhan 是静态的,使用的锁对象必须是固定的类名.class
    // 如果是静态方法,加锁后,自动分配的锁对象就是类名.class
    static public LanHanSingleton Born() {
        synchronized (LanHanSingleton.class){
            if (lanhan == null) {
                lanhan = new LanHanSingleton();
            }
            return lanhan;
//        return lanhan = (lanhan == null) ? new LanHanSingleton() : lanhan;
        }
    }
}
